﻿using System;
using System.IO;
using System.IO.IsolatedStorage;

namespace Achievements.Serialization
{
    public static class AppSettings
    {
        private static readonly IsolatedStorageFile Storage = IsolatedStorageFile.GetUserStoreForApplication();

        public static bool Contains(string key)
        {
            return Storage.FileExists(key);
        }

        public static bool Delete(string key)
        {
            if (!Storage.FileExists(key))
            {
                Storage.DeleteFile(key);
                return true;
            }
            return false;
        }

        public static void InsertOrUpdate(string key, object value)
        {
            if (value == null)
                return;

            using (IsolatedStorageFileStream stream = Storage.OpenFile(key, FileMode.OpenOrCreate))
            {
                BinarySerializer.Serialize(stream, value);
            }
        }

        /// <summary>
        /// Get the item stored at the given key, and deletes it from the container, if it exists.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns>
        ///   <c>The object.</c>
        /// </returns>
        public static object GetAndDeleteIfExists(string key)
        {
            if (!Storage.FileExists(key)) return null;

            var obj = Get<object>(key);
            Delete(key);
            return obj;
        }

        /// <summary>
        /// Gets the item of the specified Type, at the given key. Use with caution, as casting exceptions will occur if item is not of type T.
        /// </summary>
        /// <typeparam name="T">The expected Type of the item.</typeparam>
        /// <param name="key">The key.</param>
        /// <returns>
        /// The item, if it exists and is of Type T.
        /// </returns>
        public static T Get<T>(string key)
        {
            object obj;

            if (!Storage.FileExists(key)) throw new FileNotFoundException("No file exists at key");

            using (IsolatedStorageFileStream stream = Storage.OpenFile(key, FileMode.OpenOrCreate))
            {
                obj = BinarySerializer.Deserialize(stream);
            }
            if (obj is T)
                return (T) obj;

            throw new ArgumentException("Value of key is not of type " + typeof (T));
        }

        /// <summary>
        /// Gets the type of the item at the specified key in the container. Null is returned if the item does not exist.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <returns>the <c>Type</c> of the item if it exists.</returns>
        public static Type GetItemType(string key)
        {
            if (!Contains(key))
                return null;

            object obj;

            using (IsolatedStorageFileStream stream = Storage.OpenFile(key, FileMode.OpenOrCreate))
            {
                obj = BinarySerializer.Deserialize(stream);
            }
            return obj == null ? null : obj.GetType();
        }
    }
}